/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.ui.format;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import info.xmlprint.core.format.Format;
import info.xmlprint.core.format.FormatGroup;
import info.xmlprint.core.format.FormatSorter;
import info.xmlprint.core.project.PrintProject;
import info.xmlprint.core.referencesystem.ReferencingSystemGroup; 
import info.xmlprint.ui.message.GuiMessages;
import info.xmlprint.ui.widgets.ISetupComposite;
import info.xmlprint.ui.widgets.SpinnerAndCombo;

import org.apache.log4j.Logger;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.jaxen.JaxenException;
import org.jaxen.dom4j.Dom4jXPath;

/*
 * 
 */
public class FootnoteComposite extends GuiCommon implements IFormatSetup, ISetupComposite {
	private static int getTableItemIndex(TableItem ti, Table table) {
		for (int i = 0; i < table.getItemCount(); i++) {
			if (ti.equals(table.getItem(i)))
				return i;
		}

		return -1;
	}

	public static void main(String args[]) {
		Display display = Display.getDefault();
		Shell shell = new Shell(display);

		Format f1 = new Format();
		f1.setName("f1");
		Format f2 = new Format();
		f2.setName("f2");
		FormatGroup fg = new FormatGroup();
		fg.addFormat(f1);
		fg.addFormat(f2);

		new FootnoteComposite(shell, SWT.NONE, f1);

		shell.setLayout(new FillLayout());
		shell.layout();

		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}
	private Composite comp;
	private List<Format> footnoteFormatList = new ArrayList<Format>();
	private Format format;
	private FormatGroup formatGroup;

	private Logger logger = Logger.getLogger(this.getClass().getName());
	private Combo numberingCombo, rsCombo, postfixCCombo, separatorMultiple, separatorRuleColor;
	private Button positionCheckbox, useSeparatorRule, testButton, 
		noteType_footnote, noteType_endnote, counting_cont, counting_rs;
	private SpinnerAndCombo separatorRuleWidth, separatorRuleWidthLong, separatorRuleThickness;
	
	
	private Text prefixText;

	private PrintProject printProject;

	private Text resetText;

	private Action topAction, upAction, downAction, bottomAction;

	private TableViewer tv;

	//private Combo typeCCombo;
	
	private String[] original = new String[] { "black", "aqua", "blue",
			"fuchsia", "gray", "green", "lime", "maroon", "navy",
			"olive", "purple", "red", "silver", "teal", "white",
			"yellow" };

	private String[] itemListTextColor_local = new String[] {
		GuiMessages.Stileditor_ParagraphFormat_Color_Black,
		GuiMessages.Stileditor_ParagraphFormat_Color_Aqua,
		GuiMessages.Stileditor_ParagraphFormat_Color_Blue,
		GuiMessages.Stileditor_ParagraphFormat_Color_Fuchsia,
		GuiMessages.Stileditor_ParagraphFormat_Color_Gray,
		GuiMessages.Stileditor_ParagraphFormat_Color_Green,
		GuiMessages.Stileditor_ParagraphFormat_Color_Lime,
		GuiMessages.Stileditor_ParagraphFormat_Color_Maroon,
		GuiMessages.Stileditor_ParagraphFormat_Color_Navy,
		GuiMessages.Stileditor_ParagraphFormat_Color_Olive,
		GuiMessages.Stileditor_ParagraphFormat_Color_Purple,
		GuiMessages.Stileditor_ParagraphFormat_Color_Red,
		GuiMessages.Stileditor_ParagraphFormat_Color_Silver,
		GuiMessages.Stileditor_ParagraphFormat_Color_Teal,
		GuiMessages.Stileditor_ParagraphFormat_Color_White,
		GuiMessages.Stileditor_ParagraphFormat_Color_Yellow };

	public FootnoteComposite(org.eclipse.swt.widgets.Composite parent,
			int style, Format f) {
		comp = new Composite(parent, style);
		format = f;
		formatGroup = f.getFormatGroup();

		// zum Test
		if (formatGroup == null) {
			formatGroup = new FormatGroup();
			format.setFormatGroup(formatGroup);
		}

		initGUI();
		initAction();
		setDragDrop(tv.getTable());

		if (!f.getFoCategory().equals("footnote"))
			setEnabled(false);
	}

	@Override
	public boolean controlValueVertify() {
		return true;
	}

	public Composite getComp() {
		return comp;
	}

	public Format getFormat() {
		if (noteType_footnote.getSelection()) // if type is "footnote"
			format.setFootnoteAttribute("fn-type", "footnote");
		else 
			format.setFootnoteAttribute("fn-type", "endnote");
			/*if (numberingCombo.getSelectionIndex() < 3) { // predefined (a, 1,
															// i)
				format.setFootnoteAttribute("fn-numberingstyle", numberingCombo
						.getItem(numberingCombo.getSelectionIndex()));
				format.setFootnoteAttribute("fn-refSystem", "");
			} else { // referencing system
				format.setFootnoteAttribute("fn-numberingstyle", "");
				format.setFootnoteAttribute("fn-refSystem", numberingCombo
						.getItem(numberingCombo.getSelectionIndex()));
			}*/
		if (counting_cont.getSelection()) { // continuous
			format.setFootnoteAttribute("fn-numberingstyle", numberingCombo
					.getItem(numberingCombo.getSelectionIndex()));
			if (positionCheckbox.getSelection()) {
				format.setFootnoteAttribute("fn-baseline-shift", "super");
			} else {
				format.setFootnoteAttribute("fn-baseline-shift", "baseline");
			}
			
			format.setFootnoteAttribute("fn-refSystem", "");
		} else { // Referencing system
			format.setFootnoteAttribute("fn-numberingstyle", "");
			format.setFootnoteAttribute("fn-baseline-shift", "baseline");
			format.setFootnoteAttribute("fn-refSystem", rsCombo.getText());
		}
		
		format.setFootnoteAttribute("fn-prefix", prefixText.getText());
		format.setFootnoteAttribute("fn-postfix", postfixCCombo.getText());
		format.setFootnoteAttribute("fn-reset", resetText.getText());
		format.setFootnoteAttribute("fn-separator-mult", separatorMultiple.getText());
	
		if (useSeparatorRule.getSelection())
			format.setFootnoteAttribute("fn-seprule-bool", "true"); 
		else
			format.setFootnoteAttribute("fn-seprule-bool", "false");
		
		format.setFootnoteAttribute("fn-seprule-width", separatorRuleWidth.getValue());
		format.setFootnoteAttribute("fn-seprule-width-long", separatorRuleWidthLong.getValue());
		format.setFootnoteAttribute("fn-seprule-color", getOriginalValue("color", separatorRuleColor.getText()));
		format.setFootnoteAttribute("fn-seprule-thickness", separatorRuleThickness.getValue());
		
		if (tv.getTable().isEnabled()) {
			int i = 0;
			for (TableItem ti : tv.getTable().getItems()) {
				Format f = (Format) ti.getData();
				f.setId("" + i);
				i++;
			}
		}

		return format;
	}

	private void initAction() {
		topAction = new Action(GuiMessages.General_Gui_Top) {
			public void run() {
				Table table = tv.getTable();
				if (table.getSelection() == null)
					return;

				TableItem[] tis = table.getSelection();
				for (int i = tis.length - 1; i >= 0; i--) {
					Format f = (Format) tis[i].getData();
					footnoteFormatList.remove(f);
					footnoteFormatList.add(0, f);
					tv.refresh();
				}
			}
		};

		upAction = new Action(GuiMessages.General_Gui_Up) {
			public void run() {
				Table table = tv.getTable();
				if (table.getSelection() == null)
					return;

				Format currSt = (Format) table.getSelection()[0].getData();
				int index = footnoteFormatList.indexOf(currSt);
				if (index > 0) {
					Format temp = footnoteFormatList.get(index - 1);
					footnoteFormatList.set(index - 1, currSt);
					footnoteFormatList.set(index, temp);
				}
				tv.refresh();
			}
		};

		downAction = new Action(GuiMessages.General_Gui_Down) {
			public void run() {
				Table table = tv.getTable();
				if (table.getSelection() == null)
					return;

				Format currSt = (Format) table.getSelection()[0].getData();
				int index = footnoteFormatList.indexOf(currSt);
				if (index + 1 < footnoteFormatList.size()) {
					Format temp = footnoteFormatList.get(index + 1);
					footnoteFormatList.set(index + 1, currSt);
					footnoteFormatList.set(index, temp);
				}
				tv.refresh();

			}
		};

		bottomAction = new Action(GuiMessages.General_Gui_Bottom) {
			public void run() {
				Table table = tv.getTable();
				if (table.getSelection() == null)
					return;

				for (TableItem ti2 : table.getSelection()) {
					Format currSt = (Format) ti2.getData();
					int length = footnoteFormatList.size();
					footnoteFormatList.remove(currSt);
					footnoteFormatList.add(length - 1, currSt);
				}
				tv.refresh();
			}
		};
	}

	private void initGUI() {
		addInternationalMap("color", original, itemListTextColor_local);
	
		comp.setLayout(new GridLayout(2, false));
		Composite comp1 = new Composite(comp, SWT.NONE);
		
		{
			comp1.setLayout(new GridLayout(1, false));
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			comp1.setLayoutData(gd);
		}
		
		// Type of note: footnote vs. endnote
		
		Group noteType = new Group(comp1, SWT.NONE);
		noteType.setLayout(new GridLayout(2, false));
		noteType.setText(GuiMessages.Stileditor_Footnote_Type);
		noteType.setLayoutData(getGD(GridData.FILL_HORIZONTAL, 2, 0,
			0));

		{
			//addLabel(noteType, GuiMessages.Stileditor_Footnote_Type + ":");
			
			noteType_footnote = new Button(noteType, SWT.RADIO);
			noteType_footnote.setText(GuiMessages.Stileditor_Footnote_Footnote);
			
			noteType_endnote = new Button(noteType, SWT.RADIO);
			noteType_endnote.setText(GuiMessages.Stileditor_Footnote_Endnote);
			
			if (format.getFootnoteAttribute("fn-type") == "endnote")
				noteType_endnote.setEnabled(true);
			else
				noteType_footnote.setSelection(true);
		}
		
		
		Group noteOptions = new Group(comp1, SWT.NONE);
		noteOptions.setLayout(new GridLayout(3, false));
		noteOptions.setText(GuiMessages.Stileditor_Footnote_Counter);
		noteOptions.setLayoutData(getGD(GridData.FILL_HORIZONTAL, 1, 0,	0));
			
		
		// Type of counting: continuous vs. referencing system
		//addLabel(noteOptions, GuiMessages.Stileditor_Footnote_Counter);
		
		counting_cont = new Button(noteOptions, SWT.RADIO);
		counting_cont.setText(GuiMessages.Stileditor_Footnote_Continuous);
		counting_cont.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				Boolean b = counting_cont.getSelection();
				rsCombo.setEnabled(!b);
				numberingCombo.setEnabled(b);
				resetText.setEnabled(b);
				testButton.setEnabled(b);
				postfixCCombo.setEnabled(b);
				prefixText.setEnabled(b);
				positionCheckbox.setEnabled(b);
				separatorMultiple.setEnabled(b);
			}
		});
		
						
		counting_rs = new Button(noteOptions, SWT.RADIO);
		counting_rs.setText(GuiMessages.Stileditor_Footnote_RS);
		counting_rs.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				Boolean b = counting_rs.getSelection();
				rsCombo.setEnabled(b);
				numberingCombo.setEnabled(!b);
				resetText.setEnabled(!b);
				testButton.setEnabled(!b);
				postfixCCombo.setEnabled(!b);
				prefixText.setEnabled(!b);
				positionCheckbox.setEnabled(!b);
				separatorMultiple.setEnabled(!b);
			}
		});
		
		addLabel(noteOptions, "");
		
		if (!format.getFootnoteAttribute("fn-numberingstyle").isEmpty())
			counting_cont.setSelection(true);
		else
			counting_rs.setSelection(true);
		
		
		// New group for counting options
		Group counting = new Group(noteOptions, SWT.NONE);
		counting.setLayout(new GridLayout(3, false));
		//counting.setText(GuiMessages.Stileditor_Footnote_Options);
		counting.setLayoutData(getGD(GridData.FILL_HORIZONTAL, 1, 0,
			0));
		
		// Counting
		{
			addLabel(counting, GuiMessages.Stileditor_Footnote_Counter + ":");
			numberingCombo = new Combo(counting, SWT.NONE);
			numberingCombo.setItems(formatGroup.getNumberingStyleItems());
			  
			numberingCombo.setLayoutData(getGD(0, 1, 140, 0));
			numberingCombo
					.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {

						@Override
						public void widgetDefaultSelected(
								org.eclipse.swt.events.SelectionEvent e) {
							// TODO Auto-generated method stub

						}

						@Override
						public void widgetSelected(
								org.eclipse.swt.events.SelectionEvent e) {
							// TODO Auto-generated method stub
							
							 /*if (numberingCombo.getSelectionIndex() == 3) { //
								 Referenz refSystem.setEnabled(true);
							 } else { refSystem.setEnabled(false); }*/
							 
						}
					});
			
			String s = format.getFootnoteAttribute("fn-numberingstyle");
			if (!s.isEmpty()) {
				counting_cont.setSelection(true);
				numberingCombo.setText(s);
			} else {		
				counting_rs.setSelection(true);
				numberingCombo.select(0);
			}
			
			addLabel(counting, "");
		}
		
		// reset
		{
			addLabel(counting, GuiMessages.Stileditor_Footnote_Reset + ":");

			resetText = new Text(counting, SWT.SINGLE | SWT.BORDER);
			//GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
			//resetText.setLayoutData(gridData);
			resetText.setLayoutData(getGD(0, 1, 140, 0));
			resetText.setText(format.getFootnoteAttribute("fn-reset"));
			resetText.setToolTipText(GuiMessages.Stileditor_Gui_AddXPath);
			resetText.addListener(SWT.KeyDown, new Listener() {
				public void handleEvent(Event e) { // use ENTER as a shortcut
					if (e.keyCode == SWT.CR)
						xpathTest(resetText.getText());
				}
			});

			testButton = new Button(counting, SWT.NONE);
			testButton.setLayoutData(getGD(0, 1, 100, 0)); // TODO: Check, whether narrow box under Linux
			testButton.setText("" + GuiMessages.Stileditor_Gui_Check + "");
			testButton.addListener(SWT.Selection, new Listener() {
				public void handleEvent(Event e) {
					xpathTest(resetText.getText());
				}
			});
		}

		// Präfix
		{
			addLabel(counting, GuiMessages.Stileditor_Footnote_Prefix + ":");
			prefixText = new Text(counting, SWT.NONE);
			prefixText.setText(format.getFootnoteAttribute("fn-prefix"));
			prefixText.setLayoutData(getGD(0, 1, 110, 20));
			addLabel(counting, "");
		}

		// postfix
		{
			addLabel(counting, GuiMessages.Stileditor_Footnote_Postfix + ":");
			postfixCCombo = new Combo(counting, SWT.NONE);
			postfixCCombo.setItems(postfixItems);
			postfixCCombo.setLayoutData(getGD(0, 1, 100, 0));
			postfixCCombo.setText(format.getFootnoteAttribute("fn-postfix"));
			addLabel(counting, "");
		}
		
		
		{
			addLabel(counting, GuiMessages.Stileditor_Footnote_Superscript + ":");
			positionCheckbox = new Button(counting, SWT.CHECK);
			positionCheckbox.setLayoutData(getGD(0, 2, 70, 0));
			if (format.getFootnoteAttribute("fn-baseline-shift")
					.equalsIgnoreCase("super")) {
				positionCheckbox.setSelection(true);
			} else {
				positionCheckbox.setSelection(false);
			}
		}
		
		{
			// Set string for separating multiple footnotes
			addLabel(counting, GuiMessages.Stileditor_Footnote_Separator);
			separatorMultiple = new Combo(counting, SWT.DROP_DOWN);
			separatorMultiple.setLayoutData(getGD(0, 1, 100, 0));
			separatorMultiple.add(",");
			separatorMultiple.add(",\u2423");
			separatorMultiple.add("\u2423");
			
			String s = format.getFootnoteAttribute("fn-seprule-mult");
			if (!s.isEmpty())
				separatorMultiple.setText(s);
			else
				separatorMultiple.select(0);
			
			addLabel(counting, "");
		}
				
		
		Group referencingSystem = new Group(noteOptions, SWT.NONE);
		referencingSystem.setLayout(new GridLayout(2, false));
		//referencingSystem.setText(GuiMessages.Stileditor_Footnote_Options);
		referencingSystem.setLayoutData(getGD(GridData.FILL_BOTH, 1, 0,
			0));
		
		addLabel(referencingSystem, GuiMessages.Stileditor_Footnote_RS);
		rsCombo = new Combo(referencingSystem, SWT.NONE);
		  
		rsCombo.setLayoutData(getGD(0, 1, 170, 0));
		rsCombo
				.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {

					@Override
					public void widgetDefaultSelected(
							org.eclipse.swt.events.SelectionEvent e) {
						// TODO Auto-generated method stub

					}

					@Override
					public void widgetSelected(
							org.eclipse.swt.events.SelectionEvent e) {
						// TODO Auto-generated method stub
						
						 /*if (numberingCombo.getSelectionIndex() == 3) { //
							 Referenz refSystem.setEnabled(true);
						 } else { refSystem.setEnabled(false); }*/
						 
					}
				});
		
		if (format.getFootnoteAttribute("fn-refSystem").isEmpty() && rsCombo.getItemCount() > 0)
			rsCombo.select(0);
		
		addLabel(noteOptions, "");
		
		Group separatorRule = new Group(noteOptions, SWT.NONE);
		separatorRule.setLayout(new GridLayout(2, false));
		referencingSystem.setLayoutData(getGD(GridData.FILL_BOTH, 1, 0,	0));
		separatorRule.setText(GuiMessages.Stileditor_Footnote_Separator_Rule);
		
		{ // Use rule as footnote separator 
			addLabel(separatorRule, GuiMessages.Stileditor_Footnote_Separator_Rule_Output);
			useSeparatorRule = new Button(separatorRule, SWT.CHECK);
			useSeparatorRule.setLayoutData(getGD(0, 1, 70, 0));
			useSeparatorRule.addListener(SWT.Selection, new Listener() {
				@Override
				public void handleEvent(Event event) {
					Boolean b = useSeparatorRule.getSelection();
					separatorRuleColor.setEnabled(b);
					separatorRuleWidth.setEnabled(b);
					separatorRuleWidthLong.setEnabled(b);
					separatorRuleThickness.setEnabled(b);
				}
			});
			useSeparatorRule.setSelection(format.getFootnoteAttribute("fn-seprule-bool").equalsIgnoreCase("true"));
		}
		
		{ // Color of footnote separator
			addLabel(separatorRule, GuiMessages.Stileditor_Footnote_Separator_Rule_Color);
			separatorRuleColor = new Combo(separatorRule, SWT.NONE);
			separatorRuleColor.setLayoutData(getGD(0, 1, 150, 0));
			separatorRuleColor.setItems(itemListTextColor_local);
					
			String s = getLocalValue("color", format.getFootnoteAttribute("fn-seprule-color"));
			if (!s.isEmpty())
				separatorRuleColor.setText(s);
			else
				separatorRuleColor.select(0);
		}
		
		{ // Width of footnote separator
			addLabel(separatorRule, GuiMessages.Stileditor_Footnote_Separator_Rule_Width);
			separatorRuleWidth = new SpinnerAndCombo(separatorRule, 0);
			
			String s = format.getFootnoteAttribute("fn-seprule-width");
			if (!s.isEmpty())
				separatorRuleWidth.setValue(s);
			else
				separatorRuleWidth.setValue("1cm");
		}
		
		{ // Width of footnote separator for broken footnotes
			addLabel(separatorRule, GuiMessages.Stileditor_Footnote_Separator_Rule_Width_Long);
			separatorRuleWidthLong = new SpinnerAndCombo(separatorRule, 0);
			Combo c = (Combo) separatorRuleWidthLong.getChildren()[2];
			c.add("%");
			
			String s = format.getFootnoteAttribute("fn-seprule-width-long");
			if (!s.isEmpty())
				separatorRuleWidthLong.setValue(s);
			else
				separatorRuleWidthLong.setValue("1");
		}
		
		{ // Thickness of footnote separator rule
			addLabel(separatorRule, GuiMessages.Stileditor_Footnote_Separator_Rule_Thickness);
			separatorRuleThickness = new SpinnerAndCombo(separatorRule, 0);
			String s = format.getFootnoteAttribute("fn-seprule-thickness");
			if (!s.isEmpty())
				separatorRuleThickness.setValue(s);
			else
				separatorRuleThickness.setValue("0.4pt");
		}
		
		counting_cont.notifyListeners(SWT.Selection, new Event());
		useSeparatorRule.notifyListeners(SWT.Selection, new Event());
		
		// Rang-order of apparatus
		{
			tv = new TableViewer(comp, SWT.BORDER | SWT.NO_SCROLL
					| SWT.FULL_SELECTION);
			final Table table = tv.getTable();

			GridData gd = new GridData(GridData.FILL_BOTH);
			gd.widthHint = 300;
			table.setLayoutData(gd);
			table.setHeaderVisible(true);
			table.setLinesVisible(true);
			table.addListener(SWT.MenuDetect, new Listener() {
				public void handleEvent(Event event) {

					if (table.getSelection() == null
							|| table.getSelectionCount() < 1)
						return;

					final TableItem ti = table.getSelection()[0];
					if (ti == null)
						return;

					Menu menu = new Menu(table.getShell(), SWT.POP_UP);
					{
						MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
						String typName = GuiMessages.General_Gui_Top;
						menuItem.setText(typName);

						moveItem(menuItem, topAction);
					}

					{
						MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
						String typName = GuiMessages.General_Gui_Up;
						menuItem.setText(typName);
						moveItem(menuItem, upAction);

					}
					{
						MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
						String typName = GuiMessages.General_Gui_Down;
						menuItem.setText(typName);
						moveItem(menuItem, downAction);

					}

					{
						MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
						String typName = GuiMessages.General_Gui_Bottom;
						menuItem.setText(typName);
						moveItem(menuItem, bottomAction);
					}

					menu.setVisible(true);

				}
			});

			{
				TableColumn tc = new TableColumn(table, SWT.NONE);
				tc.setText(GuiMessages.Stileditor_Footnote_Sort);
				tc.setWidth(2000);
				tc.setResizable(false);
			}

			tv.setContentProvider(new ITreeContentProvider() {
				public void dispose() {
				}

				public Object[] getChildren(Object parentElement) {
					return null;
				}

				@SuppressWarnings("unchecked")
				public Object[] getElements(Object inputElement) {
					if (inputElement instanceof List) {
						return ((List<Format>) inputElement).toArray();
					}
					return null;
				}

				public Object getParent(Object element) {
					return null;
				}

				public boolean hasChildren(Object element) {
					return false;
				}

				public void inputChanged(Viewer viewer, Object oldInput,
						Object newInput) {
				}

			});

			tv.setLabelProvider(new ITableLabelProvider() {
				public void addListener(ILabelProviderListener listener) {
				}

				public void dispose() {
				}

				public Image getColumnImage(Object element, int columnIndex) {
					return null;
				}

				public String getColumnText(Object element, int columnIndex) {
					if (element instanceof Format) {
						Format f = (Format) element;

						if (columnIndex == 0) {
							return f.getName();
						}
					}
					return null;
				}

				public boolean isLabelProperty(Object element, String property) {
					return false;
				}

				public void removeListener(ILabelProviderListener listener) {

				}
			});

			for (Format f : format.getFormatGroup().getFormats()) {
				if (f.getFoCategory().equals("footnote"))
					footnoteFormatList.add(f);
			}
			Collections.sort(footnoteFormatList, new FormatSorter("footnote"));
			tv.setInput(footnoteFormatList);

		}
		// toolComp
		{
			Composite toolComp = new Composite(comp, SWT.NONE);
			toolComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
			toolComp.setLayout(new GridLayout());
			{
				Button button = new Button(toolComp, SWT.NONE);
				button.setLayoutData(new GridData());
				button.setToolTipText(GuiMessages.General_Gui_Top);
				button.setImage(new Image(null, this.getClass()
						.getResourceAsStream("/icons/totop.png")));

				button.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event e) {
						topAction.run();
					}
				});

			}
			{
				Button button = new Button(toolComp, SWT.NONE);
				button.setLayoutData(new GridData());
				button.setToolTipText(GuiMessages.General_Gui_Up);
				button.setImage(new Image(null, this.getClass()
						.getResourceAsStream("/icons/toup.png")));
				button.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event e) {
						upAction.run();
					}
				});
			}
			{
				Button button = new Button(toolComp, SWT.NONE);
				button.setLayoutData(new GridData());
				button.setToolTipText(GuiMessages.General_Gui_Down);
				button.setImage(new Image(null, this.getClass()
						.getResourceAsStream("/icons/todown.png")));
				button.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event e) {
						downAction.run();
					}
				});
			}
			{
				Button button = new Button(toolComp, SWT.NONE);
				button.setLayoutData(new GridData());
				button.setToolTipText(GuiMessages.General_Gui_Bottom);
				button.setImage(new Image(null, this.getClass()
						.getResourceAsStream("/icons/tobottom.png")));
				button.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event e) {
						bottomAction.run();
					}
				});

			}

		}
	}

	private void moveItem(Widget widget, final Action action) {
		widget.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				action.run();
			}
		});

	}

	private void refreshTable() {
		if (tv.getTable().getEnabled() && !footnoteFormatList.contains(format)) {
			footnoteFormatList.add(format);
		} else if (!tv.getTable().getEnabled()
				&& footnoteFormatList.contains(format)) {
			footnoteFormatList.remove(format);
		}
		tv.refresh();
	}

	private void setDragDrop(final Table table) {
		int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;

		DragSource dragSource = new DragSource(table, operations);
		dragSource.setTransfer(new Transfer[] { TextTransfer.getInstance() });
		final TableItem[] dragSourceItem = new TableItem[1];
		dragSource.addDragListener(new DragSourceListener() {
			@Override
			public void dragFinished(DragSourceEvent event) {
			}

			@Override
			public void dragSetData(DragSourceEvent event) {
				event.data = getTableItemIndex(dragSourceItem[0], tv.getTable())
						+ "";
			}

			public void dragStart(DragSourceEvent event) {
				TableItem[] ti = tv.getTable().getSelection();
				if (ti.length == 1) {
					event.doit = true;
					dragSourceItem[0] = ti[0];
				} else {
					event.doit = false;
				}
			}
		});

		DropTarget target = new DropTarget(table, operations);
		target.setTransfer(new Transfer[] { TextTransfer.getInstance() });
		target.addDropListener(new DropTargetAdapter() {
			public void dragOver(DropTargetEvent event) {
				event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;

				if (event.item != null) {
					TableItem item = (TableItem) event.item;
					Point pt = table.getDisplay().map(null, table, event.x,
							event.y);
					Rectangle bounds = item.getBounds();
					if (pt.y < bounds.y + bounds.height / 2) {
						event.feedback |= DND.FEEDBACK_INSERT_BEFORE;
					} else {
						event.feedback |= DND.FEEDBACK_INSERT_AFTER;
					}
				}
			}

			public void drop(DropTargetEvent event) {
				String intStr = (String) event.data;
				TableItem ti = (TableItem) event.item;

				if (ti == null || intStr.equals(""))
					return;

				int sourceIndex = Integer.parseInt(intStr);

				Point point = table.getDisplay().map(null, table, event.x,
						event.y);
				Rectangle bounds = ti.getBounds();

				TableItem[] tis = table.getItems();
				int targetIndex = 0;
				for (int i = 0; i < tis.length; i++) {
					if (tis[i].equals(ti)) {
						targetIndex = i;
						break;
					}
				}

				if (targetIndex < 0)
					return;

				if (point.y < bounds.y + bounds.height / 2) {

				} else {
					targetIndex++;
				}

				List<Format> tempFormatList = new ArrayList<Format>();
				if (sourceIndex != targetIndex) {
					for (int i = 0; i < footnoteFormatList.size(); i++) {
						if (i == sourceIndex) {
							continue;
						} else if (i == targetIndex) {
							tempFormatList.add(footnoteFormatList
									.get(sourceIndex));
						}
						tempFormatList.add(footnoteFormatList.get(i));
					}
					if (targetIndex == footnoteFormatList.size()) {
						tempFormatList.add(footnoteFormatList.get(sourceIndex));
					}

					footnoteFormatList = tempFormatList;
					tv.setInput(footnoteFormatList);
					tv.refresh();
				}
			}

		});

	}

	public void setEnabled(boolean b) {
		for (Control c : comp.getChildren()) {
			if (!(c instanceof org.eclipse.swt.widgets.Label))
				c.setEnabled(b);
		}
		refreshTable();
	}

	@Override
	public void setPrintProject(PrintProject pProject) {
		printProject=pProject;		
		ReferencingSystemGroup rg = printProject.getReferencingSystemGroup();
		if (rg != null && rg.getItemNames() != null) {
			for (String rName : rg.getItemNames()) {
				rsCombo.add(rName);
			}
		}
		
		if (!format.getFootnoteAttribute("fn-refSystem").isEmpty())
			rsCombo.setText(format.getFootnoteAttribute("fn-refSystem"));
		else {
			if (rsCombo.getItemCount() > 0)
				rsCombo.select(0);
		}
			
		
		/*if (!format.getFootnoteAttribute("fn-numberingstyle").isEmpty())
			setCombo(numberingCombo,
					format.getFootnoteAttribute("fn-numberingstyle"));
		else if (!format.getFootnoteAttribute("fn-refSystem").isEmpty())
			setCombo(numberingCombo,
					format.getFootnoteAttribute("fn-refSystem"));
		else
			numberingCombo.select(0);*/
	}

	private void xpathTest(String xPathStr) {
		try {
			new Dom4jXPath(xPathStr);
			MessageDialog.openInformation(null, null,
					GuiMessages.General_Gui_Okay);
		} catch (JaxenException e) {
			logger.error("", e);
			e.printStackTrace();
			MessageDialog.openError(null, GuiMessages.Stileditor_Error_Error,
					GuiMessages.Stileditor_Error_XPathError);
		}
	}
}
